package com.opennews.openplatform.familyexpenseapi.controller

import com.opennews.openplatform.familyexpenseapi.dto.user.UpdateUserDto
import com.opennews.openplatform.familyexpenseapi.dto.user.UpdateUserPasswordDto
import com.opennews.openplatform.familyexpenseapi.dto.user.UpdateUserRolesDto
import com.opennews.openplatform.familyexpenseapi.service.UserService
import com.opennews.openplatform.myspringbootcore.dto.ApiResponse
import com.opennews.openplatform.myspringbootcore.util.getSuccessResponse
import com.opennews.openplatform.myspringbootmvccore.security.RequestIdentityExtractor
import jakarta.validation.Valid
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*

@RestController
@RequestMapping("/user")
class UserController(
    private val userService: UserService,
    private val requestIdentityExtractor: RequestIdentityExtractor,
) {
    @GetMapping("/query-details")
    fun queryDetails(@RequestParam id: String): ResponseEntity<ApiResponse<Map<String, Any?>?>> {
        val accountGroupId = requestIdentityExtractor.getClaims().accountGroupId.asString()
        val result = userService.queryDetails(accountGroupId, id)

        return getSuccessResponse(result)
    }

    @GetMapping("/query-users-not-in-account-group")
    fun queryUsersNotInAccountGroup(
        @RequestParam keyword: String,
        @RequestParam pageSize: Int,
        @RequestParam pageIndex: Int,
    ): ResponseEntity<ApiResponse<List<Map<String, Any>>>> {
        val accountGroupId = requestIdentityExtractor.getClaims().accountGroupId.asString()
        val result = userService.queryUsersNotInAccountGroup(accountGroupId, keyword, pageSize, pageIndex)

        return getSuccessResponse(result)
    }

    @GetMapping("/query-account-group-users")
    fun queryAccountGroupUsers(
        @RequestParam pageSize: Int,
        @RequestParam pageIndex: Int,
    ): ResponseEntity<ApiResponse<List<Map<String, Any>>>> {
        val accountGroupId = requestIdentityExtractor.getClaims().accountGroupId.asString()
        val result = userService.queryAccountGroupUsers(accountGroupId, pageSize, pageIndex)

        return getSuccessResponse(result)
    }

    @PostMapping("/update-current-user-password")
    fun updateCurrentUserPassword(@Valid @RequestBody data: UpdateUserPasswordDto): ResponseEntity<ApiResponse<Boolean>> {
        val claims = requestIdentityExtractor.getClaims()

        // Checks if the current password is correct. Otherwise, the password will not be updated.
        val isPasswordMatched = userService.validatePassword(claims.username, data.currentPassword)

        // If the current password matches then update to the new password.
        if (isPasswordMatched) {
            userService.updatePassword(claims.accountGroupId.asString(), claims.username, data.newPassword)
        }

        return getSuccessResponse(isPasswordMatched)
    }

    @PostMapping("/update-current-user")
    fun updateCurrentUser(@Valid @RequestBody data: UpdateUserDto): ResponseEntity<ApiResponse<Any?>> {
        val username = requestIdentityExtractor.getClaims().username
        userService.updateCurrentUser(username, data)

        return getSuccessResponse()
    }

    @PostMapping("/update-roles")
    fun updateRoles(@Valid @RequestBody data: UpdateUserRolesDto): ResponseEntity<ApiResponse<Any?>> {
        val accountGroupId = requestIdentityExtractor.getClaims().accountGroupId.asString()
        userService.updateRoles(accountGroupId, data)

        return getSuccessResponse()
    }
}